<template>
  <div class="hotel-list-wrapper">
    <v-header ref="header" title="酒店列表"></v-header>
    <div ref="main" class="main" id="vux_view_box_body">
      <div class="top-search">
        <div class="left" @click="showCalendar = true">
          <div>
            <p style="margin-top: 1px">住<span>{{startDate.format}}</span></p>
            <p>离<span>{{endDate.format}}</span></p>
          </div>
          <i class="icon iconfont icon-down"></i>
        </div>
        <p class="right" @click="showSearch = true">
          <i class="icon iconfont icon-search"></i>
          搜索
        </p>
      </div>
      <sticky scroll-box="vux_view_box_body" :offset="isIOS ? -1 : 40 + paddingTop">
        <ul class="condition">
          <li @click="showSelectAddress = true" :class="{selected: area.id != ''}">
            <p>{{area.name}}</p>
            <i class="icon iconfont icon-down"></i>
          </li>
          <li @click="toShowPriceLevel" :class="{selected: priceAndLevel != ''}">
            <p>{{priceAndLevel != '' ? priceAndLevel : '价格等级'}}</p>
            <i class="icon iconfont icon-down"></i>
          </li>
          <li @click="showSelectSort = true" :class="{selected: selectedSort != ''}">
            <p>{{selectedSort.name}}</p>
            <i class="icon iconfont icon-down"></i>
          </li>
        </ul>
      </sticky>

      <ul class="hotel-list" v-if="hotelList.length > 0">
        <li v-for="hotel in hotelList" :key="hotel.id" @click="clickHotelItem(hotel.id)">
          <div class="thumb" v-lazy:backgroundImage="hotel.thumbnailId"></div>
          <div class="right">
            <p class="name">{{hotel.name}}</p>
            <p class="address">
              <i class="icon iconfont icon-hotel-address"></i>{{hotel.address}}</p>
            <div class="bottom">
              <p class="price">￥
                <span>{{hotel.floorPrice || 0}}</span>起</p>
              <p class="rate">{{hotel.commentScore}}分</p>
            </div>
          </div>
        </li>
      </ul>

      <p v-show="hotelList.length > 0" style="height: 44px; line-height: 44px; font-size: 13px; color: #999; text-align: center;">
        {{loadState == 'nomore' ? '~· 没有更多啦 ·~' : '正在加载...'}}
      </p>

      <not-data v-if="hotelList.length === 0" tip="没有找到酒店~" style="height: auto;"></not-data>
    </div>

    <address-selector v-model="showSelectAddress" @selectArea="selectArea" :current="area.id" @clear="clearArea"></address-selector>

    <div v-transfer-dom>
      <popup v-model="showCalendar" position="bottom" width="100%" class="popup-wrapper">
        <div style="overflow: hidden; position: relative; background: #fff; padding-bottom: 24px;">
          <calendar :zero="calendarOpt.zero" :range="calendarOpt.range" :lunar="calendarOpt.lunar" :value="calendarOpt.value" :begin="calendarOpt.begin" :end="calendarOpt.end" @select="calendarOpt.select"></calendar>
        </div>
      </popup>
    </div>

    <global-search v-model="showSearch" type="cart" :range="[0]"></global-search>

    <div v-transfer-dom>
      <popup v-model="showPriceLevel" @on-hide="resetPriceLevel" position="bottom" width="100%" class="popup-wrapper">
        <div style="position: relative; padding: 9px 12px 68px 12px; background: #fff; color: #333;" :style="{paddingBottom: paddingBottom + 68 + 'px'}">
          <p style="font-size: 16px; margin-top: 20px">
            价格范围：
            <b style="color: #00ceb9">￥{{tempPrice[0]}} - {{tempPrice[1] >= 500 ? '不限':tempPrice[1]}}</b>
            <span style="font-size: 12px">元/间</span>
          </p>
          <range v-model="tempPrice" :step="100" :max="500" @on-change="priceChange" :customStops="['￥0', '￥100', '￥200', '￥300', '￥400', '不限']" show-stops range>
          </range>

          <p style="padding: 28px 0 6px;">酒店等级</p>
          <checker v-model="tempLevel" type="checkbox" default-item-class="checker-item" selected-item-class="checker-item-selected">
            <checker-item v-for="item in hotelLevel" :key="item.value" :value="item.value">{{item.label}}</checker-item>
          </checker>
          <div :style="{paddingBottom: paddingBottom + 'px'}" style="position: absolute; left: 0; bottom: 0; right: 0; box-shadow: 0 0 10px #e9e9e9; display: flex; text-align: center; height: 40px; line-height: 40px;">
            <p @click.stop="resetPriceLevel" style="width: 40%; background: #fff;">重置筛选</p>
            <p @click.stop="submitPriceLevel" style="width: 60%; background: #00ceb9; color: #fff">显示结果</p>
          </div>
        </div>
      </popup>
    </div>

    <div v-transfer-dom>
      <popup
        v-model="showSelectSort"
        position="bottom"
        width="100%"
        class="popup-wrapper">
        <ul class="sort-list" :style="{paddingBottom: paddingBottom + 'px'}">
          <li v-for="sort in sortList" :key="sort.id" @click="selectSort(sort)" :class="{selected: sort.id === selectedSort.id}">{{sort.name}}</li>
        </ul>
      </popup>
    </div>
  </div>
</template>

<script>
import VHeader from '@/components/v-header/v-header'
import AddressSelector from '@/components/address-selector/address-selector'
import Calendar from '@/components/calendar/calendar'
import GlobalSearch from '@/components/global-search/global-search'
import Range from '@/components/range/range'
import Loading from '@/components/loading/loading'
import NotData from '@/components/not-data/not-data'
import { TransferDom, Popup, Checker, CheckerItem, Sticky } from 'vux'

import axios from '@/api/axiosApi'
import { isIphoneX, isIOS } from '@/assets/js/brower'
import { on } from '@/assets/js/dom'
import { handleBackMixin } from '@/assets/js/mixin'
import { mapGetters } from 'vuex'

export default {
  name: 'HotelList',
  mixins: [handleBackMixin],
  data() {
    return {
      showCalendar: false,
      showSelectAddress: false,
      showSearch: false,
      showPriceLevel: false,
      loadState: 'normal',
      calendarOpt: {
        zero: true,
        range: true,
        lunar: true, // 显示农历
        begin: this.moment()
          .add(1, 'months')
          .toArray()
          .slice(0, 3),
        // end: this.moment().add(30, 'days').toArray().slice(0, 3),
        weeks: ['日', '一', '二', '三', '四', '五', '六'],
        select: (begin, end) => {
          if (this.showCalendar === false) return
          this.showCalendar = false

          const beginDate = this.moment(begin).subtract(1, 'months')
          const endDate = this.moment(end).subtract(1, 'months')
          const today = this.moment()
            .toArray()
            .slice(0, 3)

          const startDiff = beginDate.diff(today, 'days')

          this.startDate = {
            date: beginDate,
            format: beginDate.format('MM-DD'),
            str: startDiff === 0 ? '今天' : beginDate.format('ddd')
          }
          this.endDate = {
            date: endDate,
            format: endDate.format('MM-DD'),
            str: endDate.format('ddd')
          }
        }
      },
      area: {
        id: '',
        name: '地区'
      },
      startDate: {
        date: this.moment(),
        format: this.moment().format('MM-DD'),
        str: '今天'
      },
      endDate: {
        date: this.moment().add(1, 'days'),
        format: this.moment()
          .add(1, 'days')
          .format('MM-DD'),
        str: '明天'
      },
      keyword: '',
      trade: '',
      price: [0, 500],
      level: [],
      tempPrice: [0, 500],
      tempLevel: [],
      hotelLevel: [
        {
          value: 5,
          label: '五星/豪华'
        },
        {
          value: 4,
          label: '四星/高端'
        },
        {
          value: 3,
          label: '三星/舒适'
        },
        {
          value: 0,
          label: '一般/经济'
        }
      ],
      showSelectSort: false,
      selectedSort: {
        id: 1,
        name: '智能排序'
      },
      sortList: [
        {
          id: 1,
          name: '智能排序'
        },
        {
          id: 2,
          name: '价格倒序',
          sortName: 'floorPrice',
          sortType: 'DESC'
        },
        {
          id: 3,
          name: '价格升序',
          sortName: 'floorPrice',
          sortType: 'ASC'
        },
        {
          id: 4,
          name: '销量排序',
          sortName: 'sale',
          sortType: 'DESC'
        },
        {
          id: 5,
          name: '离我最近',
          sortName: 'distance',
          sortType: 'DESC'
        }
      ],
      pageNum: 1,
      hotelList: [],
      allDisabledBack: true,
      allPopupModels: ['showCalendar', 'showSelectAddress', 'showSearch', 'showPriceLevel', 'showSelectSort']
    }
  },
  directives: {
    TransferDom
  },
  components: {
    VHeader,
    AddressSelector,
    Calendar,
    Popup,
    GlobalSearch,
    Range,
    Checker,
    CheckerItem,
    Sticky,
    Loading,
    NotData
  },
  computed: {
    keywordAndTrade() {
      let str = ''
      if (this.keyword !== '' && this.trade !== '') {
        str = this.keyword + '/' + this.trade
      } else if (this.keyword !== '' || this.trade !== '') {
        str = this.keyword + this.trade
      }
      return str
    },
    priceAndLevel() {
      let levelStr = ''
      if (this.level.length > 0) {
        for (let i = 0; i < this.level.length; i++) {
          const lvObj = this.hotelLevel.find(o => o.value === this.level[i])
          if (lvObj) {
            const label = lvObj.label.split('/')[1]
            levelStr === ''
              ? (levelStr = label)
              : (levelStr += '、' + label)
          }
        }
      }
      let priceStr = ''
      if (this.price[0] > 0 || this.price[1] < 500) {
        priceStr = '￥' + this.price[0] + '~￥' + this.price[1]
      }

      if ((this.price[0] > 0 || this.price[1] < 500) > 0 && this.level.length > 0) {
        return priceStr + '/' + levelStr
      }
      if (this.price[0] > 0 || this.price[1] < 500) {
        return priceStr
      }
      if (this.level.length > 0) {
        return levelStr
      }
      return ''
    },
    ...mapGetters(['areaList'])
  },
  beforeRouteEnter (to, from, next) {
    next(vm => {
      const scrollTop = vm.$store.getters.scrollTop
      if (vm.$refs.main && scrollTop.HotelList) {
        vm.$refs.main.scrollTop = scrollTop.HotelList
      }
    })
  },
  beforeRouteLeave (to, from, next) {
    this.$store.commit('SET_SCROLL_TOP', {HotelList: this.$refs.main.scrollTop})
    next()
  },
  created() {
    this.paddingBottom = 0
    this.paddingTop = 24
    this.isIOS = isIOS()
    if (isIphoneX()) {
      this.paddingTop = 34
      this.paddingBottom = 34
    }

    // 处理上个页面的
    const params = this.$route.query
    if (params) {
      if (params.areaId) {
        const obj = this.areaList.find(o => o.id === params.areaId)
        if (obj) {
          this.area = obj
        }
      }
      if (params.startDate && params.endDate) {
        const beginDate = this.moment(params.startDate)
        const endDate = this.moment(params.endDate)
        const today = this.moment().toArray().slice(0, 3)
        const startDiff = beginDate.diff(today, 'days')

        this.startDate = {
          date: beginDate,
          format: beginDate.format('MM-DD'),
          str: startDiff === 0 ? '今天' : beginDate.format('ddd')
        }
        this.endDate = {
          date: endDate,
          format: endDate.format('MM-DD'),
          str: endDate.format('ddd')
        }
      }
      if (params.price) {
        const tmpPrice = params.price.split(',')
        if (tmpPrice.length === 2) {
          this.price = [parseInt(tmpPrice[0]), parseInt(tmpPrice[1])]
        }
      }
      if (params.level) {
        const tmpLevel = params.level.split(',')
        tmpLevel.forEach(lv => {
          lv = parseInt(lv)
        })
        this.level = tmpLevel
      }
      params.keyword && (this.keyword = params.keyword)
      params.trade && (this.trade = params.trade)
    }

    this._getHotelList()
  },
  activated() {
    // 处理上个页面的
    const params = this.$route.query
    let isRefresh = false
    if (params.areaId) {
      const obj = this.areaList.find(o => o.id === params.areaId)
      if (obj && obj.id !== this.area.id) {
        isRefresh = true
        this.area = obj
      }
    }
    if (params.startDate && params.endDate) {
      const beginDate = this.moment(params.startDate)
      const endDate = this.moment(params.endDate)
      const today = this.moment().toArray().slice(0, 3)
      const startDiff = beginDate.diff(today, 'days')

      if (!beginDate.isSame(this.startDate.date)) {
        isRefresh = true
        this.startDate = {
          date: beginDate,
          format: beginDate.format('MM-DD'),
          str: startDiff === 0 ? '今天' : beginDate.format('ddd')
        }
      }
      if (!endDate.isSame(this.endDate.date)) {
        isRefresh = true
        this.endDate = {
          date: endDate,
          format: endDate.format('MM-DD'),
          str: endDate.format('ddd')
        }
      }
    }
    if (params.price && params.price !== this.price.join(',')) {
      isRefresh = true
      const tmpPrice = params.price.split(',')
      if (tmpPrice.length === 2) {
        this.price = [parseInt(tmpPrice[0]), parseInt(tmpPrice[1])]
      }
    }
    if (params.level && params.level !== this.level.join(',')) {
      isRefresh = true
      const tmpLevel = params.level.split(',')
      tmpLevel.forEach(lv => {
        lv = parseInt(lv)
      })
      this.level = tmpLevel
    }
    params.keyword && (this.keyword = params.keyword)
    params.trade && (this.trade = params.trade)

    if (isRefresh) {
      this.pageNum = 1
      this._getHotelList()
      setTimeout(() => {
        this.$refs.main.scrollTo({
          top: -50,
          behavior: 'instant'
        })
      }, 0)
    }
  },
  mounted() {
    this.$refs.main.style.height = window.innerHeight - this.$refs.header.$el.offsetHeight + 'px'

    on(this.$refs.main, 'scroll', () => {
      const scrollTop = this.$refs.main.scrollTop
      const wrapperHeight = this.$refs.main.clientHeight
      const wrapperScroll = this.$refs.main.scrollHeight
      if (this.loadState === 'normal' && wrapperScroll > wrapperHeight && (scrollTop + wrapperHeight + 1) >= (wrapperScroll - 44)) {
        this.scrollTop = scrollTop
        this.pageNum++
        this._getHotelList()
      }
    })
  },
  methods: {
    _getHotelList() {
      this.loadState = 'load'
      axios.get(
        this,
        '/v1/hotels',
        {
          pageSize: 10,
          pageNum: this.pageNum,
          areaId: this.area.id,
          maxPrice: this.price[1] >= 500 ? '' : this.price[1],
          minPrice: this.price[0] <= 0 ? '' : this.price[0],
          starRate: this.level.join(','),
          sortName: this.selectedSort.sortName,
          sortType: this.selectedSort.sortType
        },
        data => {
          if (data.length === 0) {
            if (this.pageNum > 1) {
              this.pageNum--
              this.loadState = 'nomore'
            } else {
              this.hotelList = []
            }
            return
          }
          if (this.pageNum > 1) {
            this.hotelList = this.hotelList.concat(data)
          } else {
            this.hotelList = data
          }
          this.$nextTick(() => {
            this.loadState = 'normal'
          })
        },
        () => {
          this.loadState = 'normal'
        }
      )
    },
    selectArea(area) {
      this.showSelectAddress = false
      this.area = area
      if (this.$refs.main) {
        this.$refs.main.scrollTop = 0
      }
      this.pageNum = 1
      this._getHotelList()
    },
    clearArea() {
      this.area = {
        id: '',
        name: '地区'
      }
      this.showSelectAddress = false
      this.pageNum = 1
      this._getHotelList()
    },
    toShowPriceLevel() {
      this.tempPrice = this.price.concat([])
      this.tempLevel = this.level.concat([])
      this.showPriceLevel = true
    },
    priceChange(val) {
      this.tempPrice = val
      if (this.tempPrice[1] <= this.tempPrice[0]) {
        this.tempPrice[1] = this.tempPrice[0] + 100
      }
      if (this.tempPrice[0] >= 500) {
        this.tempPrice[0] = 500
      }
    },
    resetPriceLevel() {
      this.tempPrice = [0, 500]
      this.tempLevel = []
    },
    submitPriceLevel() {
      this.price = this.tempPrice.concat([])
      this.level = this.tempLevel.concat([])
      this.showPriceLevel = false
      this.pageNum = 1
      this._getHotelList()
    },
    selectSort(item) {
      this.selectedSort = item
      this.showSelectSort = false
      this.pageNum = 1
      this._getHotelList()
    },
    clickHotelItem(id) {
      this.$router.push({
        path: `/hotel/${id}`,
        query: {
          startDate: this.startDate.date.format('YYYY-MM-DD'),
          endDate: this.endDate.date.format('YYYY-MM-DD')
        }
      })
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '~@/assets/css/variable.styl'
@import '~@/assets/css/mixins.styl'

.checker-item
  width 24.5%
  padding 12px 0
  text-align center
  line-height 1
  font-size $font-size-desc
  border 1px solid #ccc
  margin-right -1px
  background-color #fff
.checker-item-selected
  border-color $color-theme
  color $color-theme
  background-color #e5faf8
  background-image url('../../../../../static/img/icon/checked.png')
  background-repeat no-repeat
  background-position right bottom
  background-size 15px
.selected
  color $color-theme !important
.hotel-list-wrapper
  position fixed
  top 0
  left 0
  right 0
  bottom 0
  background-color $color-background
  z-index 100
.main
  overflow-x hidden
  overflow-y auto
  -webkit-overflow-scrolling touch
  -webkit-box-sizing border-box
.top-search
  margin 8px 16px
  border-radius 15px
  padding 0 12px
  height 30px
  line-height 30px
  background #ffffff
  border 0.5px solid #e2e2e2
  display flex
  align-items center
  .left
    font-size 10px
    color #666
    line-height 1
    border-right 0.5px solid rgba(226, 226, 226, 0.7)
    display flex
    align-items center
    span
      color $color-theme
      margin-left 4px
      font-size 11px
    i
      margin-left 4px
      margin-right 12px
      color #999
  .right
    color #999
    font-size 14px
    i
      margin-right 4px
      margin-left 12px
.condition
  display flex
  justify-content space-between
  border-bottom 1px solid #e2e2e2
  height 20px
  line-height 20px
  padding 12px 0
  background #ffffff
  li
    display flex
    justify-content center
    align-items center
    border-right .5px solid rgba(226, 226, 226, 0.7)
    font-size 15px
    color #666666
    width 33.33%
    padding 0 4px
    p
      display inline-block
      max-width 100px
      no-wrap()
    i
      font-size 12px
      margin-left 4px
      color #999999
    &:last-child
      border-right none
.sort-list
  background #ffffff
  li
    border-bottom 0.5px solid #e2d2e2
    height 45px
    line-height 45px
    font-size 15px
    padding 0 16px
    color #333333
    &:last-child
      border-bottom none
.hotel-list
  background #ffffff
  li
    display flex
    justify-content space-between
    padding 16px
    border-bottom 0.5px solid #e2e2e2
    &:last-child
      border-bottom none
  .thumb
    width 125px
    height 94px
    background-size cover
    background-repeat no-repeat
    background-position center
    border-radius 3px
  .right
    width calc(100% - 137px)
    position relative
  .name
    margin-top 2px
    line-height 1.3
    font-size 16px
    color #333333
    no-wrap()
  .address
    margin-top 8px
    font-size 12px
    line-height 1
    color #999999
    height 14px
    no-wrap()
    i
      margin-right 4px
      font-size 11px
  .bottom
    display flex
    justify-content space-between
    align-items center
    position absolute
    bottom 0
    left 0
    right 0
    line-height 1
    .price
      color $color-theme
      font-size 12px
      span
        font-size 20px
        margin-right 2px
        margin-left -1px
    .rate
      color $color-level
      font-size 14px
</style>
